package com.ltu.controller.customize;

import java.io.File;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.core.util.Assert;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.alibaba.excel.EasyExcel;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ltu.config.shiro.ShiroUtil;
import com.ltu.constant.AccountType;
import com.ltu.domain.mp_entity.AccountEntity;
import com.ltu.domain.mp_entity.OrderEntity;
import com.ltu.domain.mp_entity.UserEntity;
import com.ltu.domain.mp_entity.customize.DeviceEntity;
import com.ltu.domain.mp_entity.customize.SessionInfoEntity;
import com.ltu.enums.SysDict.QueryDayEnum;
import com.ltu.mapper.OrderMapper;
import com.ltu.mapper.UserMapper;
import com.ltu.mapper.customize.SessionInfoMapper;
import com.ltu.model.request.base.BaseFilterPageReq;
import com.ltu.model.response.base.CodeDataResp;
import com.ltu.model.response.dto.IndexStatisticsVO;
import com.ltu.model.response.excel.SessionInfoExcelVO;
import com.ltu.model.response.reagent.CustomerCountDTO;
import com.ltu.model.response.statistic.SessionInfoStatisticVO;
import com.ltu.service.AccountService;
import com.ltu.service.OrderService;
import com.ltu.service.UserService;
import com.ltu.service.customize.DeviceService;
import com.ltu.util.common.EnumUtils;
import com.ltu.vo.XcxUserOrderCountVO;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;


@Slf4j
@RestController
@RequestMapping("/statistic")
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
@Api(tags= "后台统计")
public class IndexStatisticController {
		private  final UserService userService ;
		private  final OrderService orderService ;
		private  final AccountService accountService ;
		private  final DeviceService deviceService;
		
		private  final  UserMapper  userMapper;
		private  final  OrderMapper  orderMapper;
		private  final  SessionInfoMapper  sessionInfoMapper;
	
	
	@RequiresRoles(value={AccountType.ACCOUNT_TYPE_SYS_STAFF})
	@ApiOperation(value = "后台统计首页")
	@RequestMapping(value = "/index", method = RequestMethod.GET)
	public CodeDataResp<IndexStatisticsVO> statisticsIndex() {
		IndexStatisticsVO  resp = new IndexStatisticsVO();
		Date date = new Date();
		Date beginDate =	 DateUtil.offsetDay(date, -15);
		//近15天的用户数
		List<CustomerCountDTO> data1 = this.userMapper.countUserBy15(DateUtil.formatDateTime(beginDate));
		resp.setStatisticBy2Week(data1 );
		resp.setTotalUsers( this.userService.count());
		DateTime dt = DateTime.now();
		String dateStr = DateUtil.formatDate(dt);
		String startTime =  dateStr+" 00:00:00";
		String endTime =	dateStr+" 23:59:59";
		QueryWrapper<UserEntity>  qw = new QueryWrapper<UserEntity>();
		qw.lambda().ge(UserEntity ::getCreateTime,startTime )
				   .le(UserEntity :: getCreateTime,endTime );
		resp.setTodayUsers( this.userService.count(qw));
		
		List<CustomerCountDTO> countOrder15 = this.userMapper.countOrderBy15(DateUtil.formatDateTime(beginDate));	
	
		
		QueryWrapper<OrderEntity> oQW = new QueryWrapper<OrderEntity>();
		oQW.lambda().eq(OrderEntity :: getPayStatus, 1)
		;
		resp.setTotalOrders( this.orderService.count(oQW));
		
		oQW.lambda().ge(OrderEntity ::getCreateTime,startTime )
		   			.le(OrderEntity :: getCreateTime,endTime );
		resp.setTodayOrders( this.orderService.count(oQW));
		resp.setCountOrder15(countOrder15);
	
		return CodeDataResp.valueOfSuccess(resp);
	}
	

	
	@ApiOperation(value = "统计用户订单总计")
	@RequestMapping(value = "order/xcxUserOrderCountAll", method = RequestMethod.GET)
	public CodeDataResp<List<XcxUserOrderCountVO>> xcxUserOrderCountAll(@RequestParam  Integer dateDict 
			,@RequestParam(required = false) Integer userId) {
	
		UserEntity  user = this.userMapper.selectById(ShiroUtil.getPrincipalUserId());
		QueryWrapper<OrderEntity> qw = new  QueryWrapper<OrderEntity>();
		QueryWrapper<OrderEntity> qw2 = new  QueryWrapper<OrderEntity>();
		qw.lambda()
				   .eq(OrderEntity :: getPayStatus, 1);
				  
		qw2.lambda()
		   .eq(OrderEntity :: getPayStatus, 1)
		   ;
		if(userId != null) {
			qw.lambda().eq(OrderEntity :: getUserId, userId);
			qw2.lambda().eq(OrderEntity :: getUserId, userId);
		}
		if( dateDict != null && dateDict.compareTo(0)==1  && dateDict.compareTo(5) == -1) {
			 QueryDayEnum dict = EnumUtils.indexToEnum(QueryDayEnum.class,dateDict);
			 Date  curDate = new Date();
			 String startTime = " 00:00:00";
			 String endTime = " 23:59:59";
			 String today = DateUtil.formatDate(curDate);
				 String dayStr =   DateUtil.formatDate(DateUtil.offsetDay(curDate, dict.getValue()));
				 qw.lambda().ge(OrderEntity :: getCreateTime, dayStr.concat(startTime));
				 qw.lambda().le(OrderEntity :: getCreateTime, today.concat(endTime));
				
		 } 
	
		List<XcxUserOrderCountVO> aa = new ArrayList<XcxUserOrderCountVO>(2);
		XcxUserOrderCountVO  resp =	orderMapper.xcxUserOrderCountAll(qw);
		aa.add( resp);
		XcxUserOrderCountVO  resp2 =	orderMapper.xcxUserOrderCountAll(qw2);
		aa.add( resp2);
		return CodeDataResp.valueOfSuccess( aa );
	
	}
	

	

	
	private QueryWrapper<OrderEntity>  getCondition(BaseFilterPageReq<OrderEntity> req) {
		AccountEntity  acc=  this.accountService.getById(ShiroUtil.getPrincipalUserId());
		QueryWrapper<OrderEntity> qw = new QueryWrapper<OrderEntity>();
		qw.lambda().eq(OrderEntity :: getPayStatus,1)
					;
		
		if(StringUtils.isNotBlank(req.getStartTime())) {
				qw.ge("o.create_time",req.getStartTime());
		}
		if(StringUtils.isNotBlank(req.getEndTime())) {
			
				qw.le("o.create_time",req.getEndTime());
		}
		if(req.getEntityParam().getUserId()!=null) 
			qw.lambda().eq(OrderEntity :: getUserId,req.getEntityParam().getUserId());
		
		if(StringUtils.isNotBlank(req.getEntityParam().getProductName())) 
			qw.like("d.product_name", req.getEntityParam().getProductName())
		;
		return qw;
	}

	
	@ApiOperation(value = "导出-对话统计")
	@PostMapping("/export")
	public CodeDataResp export(@RequestBody(required = false) BaseFilterPageReq<SessionInfoEntity> req ) {
		if(req==null || StringUtils.isBlank(req.getStartTime()) || StringUtils.isBlank(req.getEndTime()))
			return CodeDataResp.valueOfFailed("时间范围必传");
		//找出所有设备
		List<DeviceEntity> devices = this.deviceService.list();
		if(Assert.isEmpty(devices))
			return CodeDataResp.valueOfFailed("没有设备");
		//根据设备和会话领域统计会话
		QueryWrapper<SessionInfoEntity> qw = new QueryWrapper<SessionInfoEntity>();
		qw.lambda().gt(SessionInfoEntity :: getDeviceId, 0)
		.ge(SessionInfoEntity :: getCreateTime,req.getStartTime())
		.le(SessionInfoEntity :: getCreateTime,req.getEndTime())
		;
		List<SessionInfoStatisticVO> sessionData = this.sessionInfoMapper.countByDeviceAndfield(qw);
		Map<String,List<SessionInfoStatisticVO>> sessionMaps = new HashMap<String, List<SessionInfoStatisticVO>>();
		if(!Assert.isEmpty(sessionData)) 
			sessionMaps  = sessionData.stream().collect(Collectors.groupingBy( a -> a.getDeviceId().toString()));
		List<SessionInfoExcelVO>  exportData = new ArrayList<SessionInfoExcelVO>(devices.size());
		for (DeviceEntity   device : devices) {
				SessionInfoExcelVO vo = new SessionInfoExcelVO();
				vo.setDeviceNo(device.getDeviceNo());
				vo.setDeviceId(Integer.parseInt(device.getId()));
				vo.setDeviceName(device.getDeviceName());
				vo.setDeviceArea(device.getDeviceArea());
				vo.setDeviceType(device.getDeviceType());
				vo.setSessionTotal(0);
				vo.setUserTotal(0);
				vo.setFieldTotal1(0);
				vo.setFieldTotal2(0);
				vo.setFieldTotal3(0);
				vo.setFieldTotal4(0);
				vo.setFieldTotal5(0);
				vo.setFieldTotal6(0);
				vo.setFieldTotal7(0);
				vo.setFieldTotal8(0);
				exportData.add(vo);
				if(!sessionMaps.containsKey(device.getId()))
					continue;
				setFieldTotal(sessionMaps.get(device.getId()),vo);
				
		}
		QueryWrapper<UserEntity> qw2 = new QueryWrapper<UserEntity>();
		qw2.lambda().gt(UserEntity :: getDeviceId, 0)
		.ge(UserEntity :: getCreateTime,req.getStartTime())
		.le(UserEntity :: getCreateTime,req.getEndTime())
		;
		List<SessionInfoStatisticVO> sessionData2 = this.sessionInfoMapper.countUserByDevice(qw2);
		Map<Integer,SessionInfoStatisticVO> userMaps2 = new HashMap<Integer, SessionInfoStatisticVO>();
		if(!Assert.isEmpty(sessionData2)) 
			userMaps2  = sessionData2.stream().collect(Collectors.toMap(a -> a.getDeviceId(), a -> a));
		//统计设备来源
		for (SessionInfoExcelVO item : exportData) {
			if(!userMaps2.containsKey(item.getDeviceId()))
				continue;
			item.setUserTotal(userMaps2.get(item.getDeviceId()).getTotal());
		}
////		response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
////		response.setCharacterEncoding("utf-8");
////		String fileName = URLEncoder.encode("人员信息.xlsx", "UTF-8");
////		response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
		
		String  name = "咨询统计";
		String fileName =DatePattern.PURE_DATETIME_FORMAT.format(new Date())+name+".xlsx";
		String folderStr="excel".concat(File.separator).concat("export");
		String userDir = System.getProperties().getProperty("user.dir").concat(File.separator).concat("static");
		String uploadPath = userDir.concat(File.separator).concat(folderStr );
		String filePath = uploadPath.concat(File.separator).concat(fileName);
		String  returnPath="excel".concat("/").concat("export").concat("/").concat(fileName);
		log.info("保存路径：{},返回地址{}",filePath,returnPath);
		EasyExcel.write(filePath, SessionInfoExcelVO.class).sheet(name).doWrite(exportData);
//		EasyExcel.write(response.getOutputStream()).sheet("人员信息").doWrite(datas);
		return  CodeDataResp.valueOfSuccess(returnPath);
		
	}
	
	private void setFieldTotal(List<SessionInfoStatisticVO>  items,SessionInfoExcelVO vo){
		Integer total = 0;
		for (SessionInfoStatisticVO item : items) {
			total = total + item.getTotal();
			if(item.getSessionFieldId()==1)
				vo.setFieldTotal1(item.getTotal());
			if(item.getSessionFieldId()==2)
				vo.setFieldTotal2(item.getTotal());
			if(item.getSessionFieldId()==3)
				vo.setFieldTotal3(item.getTotal());
			if(item.getSessionFieldId()==4)
				vo.setFieldTotal4(item.getTotal());
			if(item.getSessionFieldId()==5)
				vo.setFieldTotal5(item.getTotal());
			if(item.getSessionFieldId()==6)
				vo.setFieldTotal6(item.getTotal());
			if(item.getSessionFieldId()==7)
				vo.setFieldTotal7(item.getTotal());
			if(item.getSessionFieldId()==8 || item.getSessionFieldId()==0)
				vo.setFieldTotal8(item.getTotal());
		}
		vo.setSessionTotal(total);
	}
	

	
	
	
	
	
	
}
